package com.feather.tenia.oracle.saver;

import java.io.CharArrayReader;
import java.io.IOException;
import java.io.Writer;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import oracle.jdbc.OracleTypes;
import oracle.jdbc.driver.OracleConnection;
import oracle.sql.CLOB;

import com.feather.common.data.Column;
import com.feather.common.db.DbSaver;

/**
 * @author flogyin
 */
public class String_CLOB implements DbSaver {
	@Override
	@SuppressWarnings("rawtypes")
	public Class getJavaType() {
		return String.class;
	}

	@Override
	public String getDbType() {
		return "clob";
	}

	@Override
	public int getSqlType() {
		return OracleTypes.CLOB;
	}

	@Override
	public boolean matchNull() {
		return true;
	}

	@Override
	public boolean save(Object value, PreparedStatement statement, Column column) throws SQLException {
		Connection connection = statement.getConnection();
		if (connection instanceof OracleConnection) {
			forOracleConnection(value, statement, column);
		} else {
			if (value != null) {
				String chars = (String) value;
				CharArrayReader car = new CharArrayReader(chars.toCharArray());
				statement.setCharacterStream(column.getOrdinal(), car, chars.length());
			} else {
				statement.setClob(column.getOrdinal(), CLOB.empty_lob());
			}
		}
		return true;
	}

	private void forOracleConnection(Object value, PreparedStatement statement, Column column) throws SQLException {
		CLOB clob = null;
		if (value != null) {
			clob = CLOB.createTemporary(statement.getConnection(), false, CLOB.DURATION_SESSION);
			String str = (String) value;

			Writer writer = null;
			try {
				writer = clob.getCharacterOutputStream();
				writer.write(str);
			} catch (IOException ex) {
				throw new SQLException(ex.getMessage());
			} finally {
				if (writer != null) {
					try {
						writer.close();
					} catch (IOException ex) {
						ex.printStackTrace();
					}
				}
			}
		} else {
			clob = CLOB.empty_lob();
		}
		statement.setClob(column.getOrdinal(), clob);
	}
}
